extern  FILE* fp;
#undef INSTR_REC
#define INSTR_REC(x) #x,

LPTSTR instr_name[]= {
#include "instr_id_def.h"
"unused"
};

//
//
//
//

int n_RoV=0;
int n_uop=0;


int RoVid[10];
int n_op;
int n_uop;

int n_tmp;


void print_alu (bool b_dir)
{
bool b_rmm;
int n_dst=0;

n_RoV=0;
n_uop=0;
n_op=0;
n_tmp=0;

//
// rm byte exists?
//
//
if (instr_desc.op1==rm8)
printf (fp,"int op_size=8;\n");
else if (instr_desc.op1==rm16)
printf (fp,"int op_size=16;\n");
else if (instr_desc.w_mask)
printf (fp,"int op_size=(code[0]&30x%x)==0)?data_size:8;\n",instr_desc.w_mask);
else
printf (fp,"int op_size=data_size;\n");

if ( instr_desc.op1<rm_max || instr_desc.op2<rm_max)
{
b_rmbyte=true;
printf (fp,"bool b_rmm=(code[1]>>6)&3)==3;\n"

}
else
b_rmbyte=false;



printf(fp, "if (!b_rmm)\n"
printf(fp,"{\n"

	//
	// op1
	//
	print_RoV(instr_desc.op1,-1);
	
	
	//
	// op2
	//
	print_RoV(instr_desc.op2,-1);
	

	
printf(fp,"}\n"
printf(fp,"else\n"
printf(fp,"{\n"

	//
	// generate address
	//
	//
	// op1
	//
	n_RoV+=print_RoV(instr_desc.op1,0);
	
	
	//
	// op2
	//
	n_RoV+=print_RoV(instr_desc.op2,0);
	
	//
	//dst
	//

	printf(fp,"}\n"
	
	//
	// funit
	//

	printf ( fp," uop[%d].funit=alu;\n"
				" uop[%d].sub_op=%s;\n"
				" uop[%d].op_size=op_size;\n"
				" uop[%d].prefix=0;\n"
				" uop[%d].src1.=r_v%d;\n"
				" uop[%d].src2.=r_v%d;\n"
				" uop[%d].dst=r_v%d.reg;\n"	
				n_uop,n_uop,instr_name[instr_desc.index],n_uop,n_uop,n_uop,RoVid[b_dir?1:0],n_uop,RoVid[b_dir?0:1],n_uop,RoVid[b_dir?1:0]);
	n_uop ++;

	//
	// if dir and b_rmm, writeback
	//

	if (b_dir)
	{

printf(fp, "if (!b_rmm)\n"
printf(fp,"{\n"

	printf ( fp," uop[%d].funit=lsq;\n"
				" uop[%d].sub_op=ST;\n"
				" uop[%d].op_size=op_size;\n"
				" uop[%d].prefix=uop[1].prefix;\n"
				" uop[%d].src1.=uop[1].src1;\n"
				" uop[%d].src2.=uop[1].src2;\n"
				" uop[%d].src3.=r_v%d;\n"	
				n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,RoVid[b_dir?1:0]);
	n_uop ++;

	printf(fp,"}\n"

	}


}




//
//  Rov id for ops.
//


print_RoV(OPERAND_TYPE op,bool b_rmm )
{
	int n_seg,n_addr;


	switch( op)
	{
		case rm:  // never place rm in other pos
		case rm16: 
			if ( b_rmm)
			{
			printf ( fp, " RoV r_v%d;\n"
				         " if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
						 "  else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm):\n",n_uop,n_RoV,n_uop,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|(seg==7?(stack?SS:DS):seg);// srg reg\n",n_RoV,n_RoV);

			n_seg=n_RoV;


			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(op_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			RoVid[n_op++]=n_RoV;

			n_RoV++;
			printf ( fp, " LDuop(%d, op_size,r_v%d,r_v%d, TMP%d|(op_size==16?0x10:0x20)); // rm16\n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;

			}
			else
			{
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =(op_size==32)?((code[0]&7)|0x20):(op_size==16)?(((code[0]>>3)&7)|0x10:(((code[0]>>3)&7));\n");
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			}

			break;
		//case rm8:


		case rm16:
			printf ( fp, " RoV r_v%d;\n"
				         " if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
						 "  else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm):\n",n_uop,n_RoV,n_uop,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|(seg==7?(stack?SS:DS):seg);// srg reg\n",n_RoV,n_RoV);

			n_seg=n_RoV;


			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(op_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			RoVid[n_op++]=n_RoV;

			n_RoV++;
			printf ( fp, " LDuop(%d, op_size,r_v%d,r_v%d, TMP%d|(data_size==16?0x10:0x20)); // rm16\n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;

			break;

		case rmf  :  			
			printf ( fp, " RoV r_v%d;\n"
				         " if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
						 "  else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm):\n",n_uop,n_RoV,n_uop,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|(seg==7?(stack?SS:DS):seg);// srg reg\n",n_RoV,n_RoV);

			
			n_seg=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(data_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);



		

			n_RoV++;
			printf ( fp, " LDuop(%d, data_size,r_v%d,r_v%d, TMP%d|(data_size==16?0x10:0x20)); \n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;

			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(data_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			RoVid[n_op++]=n_RoV;
			n_RoV++;

			printf ( fp, " LDuop(%d, 16,r_v%d,r_v%d, TMP%d|(data_size==16?0x10:0x20));// seg is 16 bit \n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;


			break;




		case dacc :// 

 
		case mspd  :// pop   
	       
		case bxp   : // gen address [ bx +al]
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(addr_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);

			printf ( fp," uop[%d].funit=alu;\n"
						" uop[%d].sub_op=movzx;\n"
						" uop[%d].op_size=8;\n"
						" uop[%d].prefix=0;\n"
						" uop[%d].src1.va=false;\n"
						" uop[%d].src1.reg=AL;\n"					

						" uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n"	
						n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp);
			n_uop ++;
			printf ( fp," uop[%d].funit=alu;\n"
						" uop[%d].sub_op=add;\n"
						" uop[%d].op_size=addr_size;\n"
						" uop[%d].prefix=0;\n"
						" uop[%d].src1.va=false;\n"
						" uop[%d].src1.reg=TMP%d|(addr_size==16?0x10:0x20);\n"
						" uop[%d].src2.va=false;\n"
						" uop[%d].src2.reg=BX|(addr_size==16?0x10:0x20);\n"
						" uop[%d].dst=TMP%d|(addr_size==16?0x10:0x20);\n"	
						n_uop,n_uop,n_uop,n_uop,n_uop,n_uop,n_tmp,n_uop,n_uop,n_uop,n_tmp);
			n_addr=n_RoV;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|DS;// seg reg DS\n",n_RoV,n_RoV,n_RoV);

  		    n_seg=n_RoV;
			n_RoV++;

			printf ( fp, " LDuop(%d, 16,r_v%d,r_v%d, TMP%d|(data_size==16?0x10:0x20)); // rm16\n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_RoV++;

			break;
 
		case acc:

			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg = (op_size==32)?EAX:(op_size==16)?AX:AL; \n",n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case const_3 :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=true;\n"
						" r_v%d.value=3; \n",n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case sreg  :  
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =(op_size==32)?((code[0]>>3)&7)|0x40;// sreg\n");
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case REG   :    
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg = (op_size==32)?((code[0]&7)|0x20):((code[0]&7)|0x10);// no 8 bit reg",n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

 		case SREG   :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =((code[0]>>3)&3)|0x40;// seg reg\n");
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case reg://
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =(op_size==32)?(((code[0]>>3)&7)|0x20):(op_size==16)?(((code[0]>>3)&7)|0x10:(((code[0]>>3)&7));\n");
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case fs_gs    : 
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =((code[0]&0x8)?GS:FS)|0x40;// seg reg\n");
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case imm      :// op1 is imm. so no rm byte
			if ( b_rmm )
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=(op_size==32)?imm:(imm & 0xffff);\n",n_RoV,n_RoV,n_RoV);
			else
  			printf ( fp," op1.va=true;\n"
			            "op1.value=(op_size==8)?code[1]:((op_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1));\n");

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case imm_8    : 
			if ( b_rmm )
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=imm & 0xff;\n",n_RoV,n_RoV);
			else
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=code[%d];\n",n_RoV,n_RoV,n_op==1? 3:1);


			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;


		case rel      :
  			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=(op_size==8)?code[1]:((op_size==16)?*(unsigned short *)(code+1):*(unsigned long  *)(code+1));\n");

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;
		case imm_8    : 
			if ( b_rmm )
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=imm & 0xff;\n",n_RoV,n_RoV);
			else
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=code[%d];\n",n_RoV,n_RoV,n_op==1? 3:1);


			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case rel_8    : 
 			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=code[1];// imm8\n",
						n_RoV,n_RoV,n_RoV);
	
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;
		case imm_16   : 
			if ( b_rmm )
			printf ( fp,"  RoV r_v%d;\n"
					"  r_v%d.va=true;\n"
					"  r_v%d.value=imm & 0xffff;\n",n_RoV,n_RoV);
			else
 			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=*(unsigned short *)(code+1);// imm16\n",
						n_RoV,n_RoV,n_RoV);

		
			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case imm_off  : 
		printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=(addr_size==16?:*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// offset\n",
						n_RoV,n_RoV,n_RoV);

		
			RoVid[n_op++]=n_RoV;

			n_RoV++;
			break;

		case imm_far  : 
		printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=(addr_size==16?:*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// offset\n",
						n_RoV,n_RoV,n_RoV);

		
			RoVid[n_op++]=n_RoV;

			n_RoV++;
			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=(addr_size==16?:*(unsigned short *)(code+3):*(unsigned long  *)(code+5);// seg\n",
						n_RoV,n_RoV,n_RoV);

			
			RoVid[n_op++]=n_RoV;
			n_RoV++;

			break;


	
		case mem_off   :
			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=true;\n"
						"  r_v%d.value=(addr_size==16?:*(unsigned short *)(code+1):*(unsigned long  *)(code+1);// direct addressing\n",
						n_RoV,n_RoV,n_RoV);

			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|(seg==7?DS:seg);// srg reg\n",n_RoV,n_RoV);

			
			n_seg=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(op_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);

			RoVid[n_op++]=n_RoV;

		

			n_RoV++;
			printf ( fp, " LDuop(%d, op_size,r_v%d,r_v%d, TMP%d|(data_size==16?0x10:0x20)); \n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;


			break;


		case ds_si   : 
			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=false;\n"
						"  r_v%d.reg = SI|(addr_size==32?0x20:0x10);// srg reg\n",n_RoV,n_RoV,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|DS;// srg reg DS \n",n_RoV,n_RoV);

			n_seg=n_RoV;


			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(op_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			RoVid[n_op++]=n_RoV;

			n_RoV++;
			printf ( fp, " LDuop(%d, 16,r_v%d,r_v%d, TMP%d|(op_size==16?0x10:0x20)); // rm16\n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;
			break;
		case es_di   :
			printf ( fp,"  RoV r_v%d;\n"
						"  r_v%d.va=false;\n"
						"  r_v%d.reg = DI|(addr_size==32?0x20:0x10);// srg reg\n",n_RoV,n_RoV,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|ES;// srg reg ES \n",n_RoV,n_RoV);

			n_seg=n_RoV;


			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = TMP%d|(op_size==16?0x10:0x20);// offet 32/16 bit\n",
						n_RoV,n_RoV,n_RoV,n_tmp);


			RoVid[n_op++]=n_RoV;

			n_RoV++;
			printf ( fp, " LDuop(%d, 16,r_v%d,r_v%d, TMP%d|(op_size==16?0x10:0x20)); // rm16\n",
					n_uop,n_seg, n_addr,n_tmp);

			n_tmp++;
			n_uop++;
			break;

		case r16    :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=false;\n"
						" r_v%d.reg =reg=((code[1]>>3)&7)|0x10; // r16\n",
						n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case cflag :// have no idea now

		case const_cf :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=true;\n"
						" r_v%d.value =0x1;// mask of CF\n",
						n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;
			break;

		case const_if :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=true;\n"
						" r_v%d.value =0x200;// mask of IF\n",
						n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;.
			break;
		case const_df :
			printf ( fp," RoV r_v%d;\n"
						" r_v%d.va=true;\n"
						" r_v%d.value = 0x400;// mask of DF\n",
						n_RoV,n_RoV,n_RoV);

			RoVid[n_op++]=n_RoV;
			n_RoV++;.

			break;
			}
			
}








gen_address(OPERAND_TYPE op,bool b_rmm,int & n_addr, int & n_seg )
{
	int n_seg,n_addr;


	switch( op)
	{
		case rm:  // never place rm in other pos
		case rm8:
		case rm16:
		case rmf  :  			
			printf ( fp, " RoV r_v%d;\n"
				         " if(addr_size==32) uop_addrg_addr32(code,uop[%d],r_v%d,stack,imm);\n"
						 "  else uop_addrg_addr16(code,uop[%d],r_v%d,stack,imm):\n",n_uop,n_RoV,n_uop,n_RoV);
			n_addr=n_RoV;

			n_RoV++;
			printf ( fp, " RoV r_v%d;\n"
						"    r_v%d.va=false;\n"
						"    r_v%d.reg = 0x40|(seg==7?(stack?SS:DS):seg);// srg reg\n",n_RoV,n_RoV);

			
			n_seg=n_RoV;
		break;
